

#ifndef __CORTISOL_AVCODEC_H
#define __CORTISOL_AVCODEC_H

class AVCodecLib
{
	HMODULE handle;

	typedef int(*avcodec_decode_video_fptr_t)(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const uint8_t *buf, int buf_size);
	avcodec_decode_video_fptr_t avcodec_decode_video_fptr;

	typedef AVCodec* (*avcodec_find_decoder_fptr_t)(enum CodecID id);
	avcodec_find_decoder_fptr_t avcodec_find_decoder_fptr;

	typedef int (*avcodec_open_fptr_t)(AVCodecContext *avctx, AVCodec *codec);
	avcodec_open_fptr_t avcodec_open_fptr;

	typedef AVFrame* (*avcodec_alloc_frame_fptr_t)(void);
	avcodec_alloc_frame_fptr_t avcodec_alloc_frame_fptr;

	typedef int (*avcodec_close_fptr_t)(AVCodecContext *avctx);
	avcodec_close_fptr_t avcodec_close_fptr;

	typedef void (*av_free_packet_fptr_t)(AVPacket *pkt);
	av_free_packet_fptr_t av_free_packet_fptr;

	typedef int (*av_lockmgr_register_fptr_t)(int (*cb)(void **mutex, enum AVLockOp op));
	av_lockmgr_register_fptr_t av_lockmgr_register_fptr;

	typedef int (*avpicture_fill_fptr_t)(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt, int width, int height);
	avpicture_fill_fptr_t avpicture_fill_fptr;

	typedef int (*avpicture_get_size_fptr_t)(enum PixelFormat pix_fmt, int width, int height);
	avpicture_get_size_fptr_t avpicture_get_size_fptr;
	

public:

	AVCodecLib() 
		:	handle(NULL) {

		Initialise();
	}

	virtual ~AVCodecLib() {

		CleanUp();
	}

	int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const uint8_t *buf, int buf_size) const {
	
		return avcodec_decode_video_fptr( avctx, picture, got_picture_ptr, buf, buf_size );
	}

	AVCodec* avcodec_find_decoder(enum CodecID id) const {

		return avcodec_find_decoder_fptr( id );
	}

	int avcodec_open(AVCodecContext *avctx, AVCodec *codec) const {

		return avcodec_open_fptr( avctx, codec );
	}

	AVFrame* avcodec_alloc_frame(void) const {

		return avcodec_alloc_frame_fptr();
	}

	int avcodec_close(AVCodecContext *avctx) const {

		return avcodec_close_fptr(avctx);
	}

	void av_free_packet(AVPacket *pkt) const {

		av_free_packet_fptr( pkt );
	}

	int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)) const {

		return av_lockmgr_register_fptr( cb );
	}

	int avpicture_fill(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt, int width, int height) const {

		return avpicture_fill_fptr( picture, ptr, pix_fmt, width,height);
	}

	int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height) const {

		return avpicture_get_size_fptr( pix_fmt, width, height);
	}

private:

	void Initialise() {

		if((handle = LoadLibrary( L"avcodec-52.dll" )) == NULL)
			throw Exception("LoadLibrary( L\"avcodec-52.dll\" )");

		RESOLVE(avcodec_decode_video);
		RESOLVE(avcodec_find_decoder);
		RESOLVE(avcodec_open);
		RESOLVE(avcodec_alloc_frame);
		RESOLVE(avcodec_close);
		RESOLVE(av_free_packet);
		RESOLVE(av_lockmgr_register);
		RESOLVE(avpicture_fill);
		RESOLVE(avpicture_get_size);
	}

	void CleanUp() {

		FreeLibrary( handle );
	}

};

#endif /*** __CORTISOL_AVCODEC_H ***/

